var service = require('./service');
var write = require('hy5b/backend/write');

var util = require('./util');

var moment = require('moment');


var today = new Date().getTime();

function isStop(date) {
  return (today - moment(date, 'YYYYMMDD').valueOf() > 864000000);
}

function roundData(arr) {
  for (var i = 0; i < arr.length; i++) {
    arr[i] = util.round(arr[i]);
  }
}

var count = 0,
  countAll = 0;

function log(recordATrue) {
  countAll++;
  if (recordATrue) {
    count++;
    console.log(countAll, count);
  } else {
    console.log(countAll + ' -');
  }
}

function fixMacd(data) {

  var macd = util.macd(
    data.macddiff[1],
    data.macddiff[2],
    data.macddea[1],
    data.klineclose[1],
    data.klineclose[0]);

  data.macddiff[0] = macd.diff;
  data.macddea[0] = macd.dea;
  data.macdmacd[0] = macd.macd;
}

function compare(a, b) {
  return parseFloat(a) > parseFloat(b);
}

// filte start
var afilter = [];
var stockData = (function() {
  var o = {};

  var fileStream;

  function parse(data) {
    var a = [];
    for (var i = 0; i < data.date.length; i++) {
      a.push([
        util.round(data.macdmacd[i]), // 0
        moment(data.date[i], 'YYYYMMDD').valueOf(),
        util.round(data.klineopen[i]), //2
        util.round(data.klinehigh[i]), //3
        util.round(data.klinelow[i]), //4
        util.round(data.klineclose[i]) //5
      ]);
    }
    return a;
  }

  return {
    DAY: 'day',
    WEEK: 'week',
    add: function(code, show, type, data) {
      if (!o[code])
        o[code] = {};
      if (!o[code][type])
        o[code][type] = parse(data);
      o[code].show = show;
    },
    remove: function(code) {
      delete o[code];
    },
    init: function(options) {
      if (options.resume) {
        //读取断点数据记录文件
        o = require('./' + options.resumeFile);
        fileStream = write(options.resumeFile, true);
      } else {
        //创建数据记录文件
        fileStream = write('tmp/data.stock');
        fileStream.write('var o={};');
        fileStream.write('module.exports=o;');
      }
    },
    record: function(code) {
      fileStream.write('o["' + code + '"]=' + JSON.stringify(o[code]) + ';');
    },
    generate: function() {
      var tmp = [];
      for (var c in o) {
        var k = o[c];
        var ohlc = [],
          macd = [];
        var i = k.day.length - 1;
        for (i; i >= 0; i--) {
          ohlc.push([
            k.day[i][1],
            parseFloat(k.day[i][2]),
            parseFloat(k.day[i][3]),
            parseFloat(k.day[i][4]),
            parseFloat(k.day[i][5])
          ]);
          macd.push({
            x: k.day[i][1],
            y: parseFloat(k.day[i][0]),
            color: k.day[i][0] > 0 ? '#ff0000' : '#00ff00'
          });
        }
        tmp.push({
          code: c,
          show: k.show,
          mdup: util.round(k.day[0][0] - k.day[1][0]),
          md2up: util.round(k.day[1][0] - k.day[2][0]),
          mwup: util.round((k.day[0][5] - k.day[0][2]) / k.day[0][2] * 100),
          // mw2up: util.round(k.week[1][0] - k.week[2][0]),
          close: k.day[0][5],
          ohlc: ohlc,
          macd: macd
        });
      }

      tmp.sort(function(a, b) {
        return a.mwup < b.mwup ? 1 : -1;
      });

      require('./print')(tmp);
    }
  }
}());

var dayCount = 3;

/**
 * [description]
 * @param  {[type]} ostock [description]
 * @param  {[type]} cb)    全回调true时才保存一条匹配成功的断点记录
 * 有一个false则停止过滤器传播，并保存一条匹配失败的断点记录
 * @return {[type]}        [description]
 */

/**
 * ### day kline up and last day macd down ### 
 */
afilter.push(function(ostock, cb) {
  var show = ostock.code + '(' + ostock.name + ')';
  var stockCode = ostock.b + ostock.code;

  service.queryDayLine(stockCode, dayCount, function(data) {

    if (!data) {
      cb(false);
      return;
    }

    if (isStop(data.date[0])) {
      cb(false);
      return;
    }

    if (compare(data.ma5avgPrice[0], data.klineclose[0])
        && compare(data.ma10avgPrice[0], data.klineclose[0])
        && compare(data.ma20avgPrice[0], data.klineclose[0])
        && compare(data.macdmacd[0], data.macdmacd[1])) {
      stockData.add(ostock.code, show, stockData.DAY, data);
      cb(true);
    } else {
      cb(false);
    }
  });
});

// afilter.push(function(ostock, cb) {
//   var show = ostock.code + '(' + ostock.name + ')';
//   var stockCode = ostock.b + ostock.code;

//   service.queryWeekLine(stockCode, dayCount, function(data) {

//     if (!data) {
//       cb(false);
//       stockData.remove(ostock.code);
//       return;
//     }

//     if (compare(data.ma5avgPrice[0], data.klineopen[0])
//         && compare(data.ma10avgPrice[0], data.klineopen[0])
//         && compare(data.ma20avgPrice[0], data.klineopen[0])
//         && compare(data.macdmacd[0], data.macdmacd[1])) {
//       stockData.add(ostock.code, show, stockData.WEEK, data);
//       cb(true);
//     } else {
//       cb(false);
//       stockData.remove(ostock.code);
//     }
//   });
// });
/*
 *
 */

/**
 * ### day macd up, week macd up ### 
afilter.push(function(ostock, cb) {
    var show = ostock.code + '(' + ostock.name + ')';
    var stockCode = ostock.b + ostock.code;

    service.queryDayLine(stockCode, dayCount, function(data) {

        fixMacd(data);

        if (isStop(data.date[0])) {
            cb(false);
            return;
        }

        if (compare(data.macdmacd[0], data.macdmacd[1])) {
            stockData.add(ostock.code, show, stockData.DAY, data);
            cb(true);
        } else {
            cb(false);
        }
    });
});

afilter.push(function(ostock, cb) {
    var show = ostock.code + '(' + ostock.name + ')';
    var stockCode = ostock.b + ostock.code;

    service.queryWeekLine(stockCode, dayCount, function(data) {
        fixMacd(data);
        if (compare(data.macdmacd[0], data.macdmacd[1])) {
            stockData.add(ostock.code, show, stockData.WEEK, data);
            cb(true);
        } else {
            stockData.remove(ostock.code);
            cb(false);
        }
    });
});
 * ### ### 
 */

/**
 * 保存断点数据filter,请勿删除
 * @param  {[type]} ostock [description]
 * @param  {[type]} cb)    {               stockData.record(ostock.code);    cb(true);} [description]
 * @return {[type]}        [description]
 */
afilter.push(function(ostock, cb) {
  stockData.record(ostock.code);
  cb(true);
});

//filter end

/**
 * [checkStock description]
 * @param  {[type]}   ostock {
 *                           b: 'sz',
 *                           code: '000003',
 *                           name: ''
 *                         }
 * @param  {Function} cb     [description]
 * @return {[type]}          [description]
 */
function checkStock(ostock, cb) {

  util.recursive(function(i, call) {
    afilter[i](ostock, function(flag) {
      if (flag) // next filter
        call();
      else {
        log(false);
        cb(false);
      }
    });
  }, afilter, 0, function() {
    //所有filter都为true
    log(true);
    cb(true);
  });
}

module.exports = {
  setOption: function(options) {
    stockData.init(options);
  },
  checkStock: checkStock,
  log: log,
  done: function() {
    stockData.generate();
    console.log('done'.green);
  }
};
